package com.org.redis.bloom;

import java.util.BitSet;

/**
 *  布隆过滤器升级版
 *  优点：能够快速的匹对数据是否存在
 *  缺点：存在一点的错误率且删除数据难度较大
 *
 *  总体来说：布隆过滤器中，判断到数据存在的情况下，有一定的几率会是误判，但如果判断到数据不存在，那一定就是不存在
 */
public class BloomFilterNew {

    private final static int DEFAULT_SIEZ = 2 << 24;

    private final static int[] SEEDS = new int[]{23,35,56,74,89,101};

    private BitSet bits;

    public SimpleHash[] func = new SimpleHash[SEEDS.length];

    public BloomFilterNew(){
        bits = new BitSet(DEFAULT_SIEZ);
        for (int i=0; i<SEEDS.length; i++){
            func[i] = new SimpleHash(DEFAULT_SIEZ, SEEDS[i]);
        }
    }

    public void add(Object value){
        for (SimpleHash f : func) {
            bits.set(f.hash(value), true);
        }
    }

    public boolean contains(Object value){
        boolean ret = true;
        for (SimpleHash f : func) {
            ret = ret && bits.get(f.hash(value));
            if (!ret) break;
        }
        return ret;
    }

    public static class SimpleHash{
        private int cap;
        private int seed;

        public SimpleHash(int cap, int seed) {
            this.cap = cap;
            this.seed = seed;
        }
        /**
         * 计算 hash 值
         */
        public int hash(Object value) {
            int h;
            return (value == null) ? 0 : Math.abs(seed * (cap - 1) & ((h = value.hashCode()) ^ (h >>> 16)));
        }
    }

    public static void main(String[] args) {
        BloomFilterNew filter = new BloomFilterNew();
        String value1 = "https://www.baidu.com";
        String value2 = "https://hcloud.com.cn";
        System.out.println(filter.contains(value1));
        System.out.println(filter.contains(value2));
        filter.add(value1);
        filter.add(value2);
        System.out.println(filter.contains(value1));
        System.out.println(filter.contains(value2));
    }
}
